﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestDataGenerator
{
    public partial class MainForm : Form
    {
        int GeneratedCount = 0;
        Generator Global_Generator;

        public MainForm()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void Cancel_button_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Check_button_Click(object sender, EventArgs e)
        {
            DBHandler dbHandler = new DBHandler { ServerName = textBoxServer.Text, Database = textBoxBase.Text, UserName = textBoxUser.Text, Pwd = textBoxPassword.Text, DomainAuth = checkBoxDomainAuth.Checked, Schema = "dbo" };
            Cursor.Current = Cursors.WaitCursor;
            bool connResult = dbHandler.Connect();
            if (!connResult)
            {
                MessageBox.Show(dbHandler.connectException.Message, MainResource.DialogHeaderError, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                SaveParams();
                OK_button.Enabled = true;
                dbHandler.CloseConnection();
                MessageBox.Show(MainResource.MessageConnectionOK, MainResource.DialogHeaderInfo, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            Cursor.Current = Cursors.Default;
        }

        private void checkBoxDomainAuth_CheckedChanged(object sender, EventArgs e)
        {
            textBoxUser.Enabled = !checkBoxDomainAuth.Checked;
            textBoxPassword.Enabled = !checkBoxDomainAuth.Checked;
            if (checkBoxDomainAuth.Checked)
            {
                textBoxUser.Text = "";
                textBoxPassword.Text = "";
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            OK_button.Enabled = false;
            toolStripStatusLabel1.Text = "";
            //
            Generator generator = ServiceProcs.LoadParamsFromXml();
            if (generator == null) return;
            //
            textBoxServer.Text = generator.dbHandler.ServerName;
            textBoxBase.Text = generator.dbHandler.Database;
            textBoxUser.Text = generator.dbHandler.UserName;
            textBoxPassword.Text = generator.dbHandler.Pwd;
            checkBoxDomainAuth.Checked = generator.dbHandler.DomainAuth;
            //
            numericUpDownFrom.Value = generator.GenerateFrom;
            numericUpDownTo.Value = generator.GenerateTo;
            textBoxPathToScript.Text = generator.PathToScript;
        }

        private void buttonOpenConfigFile_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBoxPathToScript.Text = openFileDialog1.FileName;
            }
        }

        // Процедура - обертка для записи параметров формы в xml
        private void SaveParams()
        {
            Generator generator = new Generator
            {
                dbHandler = new DBHandler { ServerName = textBoxServer.Text, Database = textBoxBase.Text, UserName = textBoxUser.Text, Pwd = textBoxPassword.Text, DomainAuth = checkBoxDomainAuth.Checked, Schema = "dbo" },
                GenerateFrom = numericUpDownFrom.Value,
                GenerateTo = numericUpDownTo.Value,
                PathToScript = textBoxPathToScript.Text
            };
            ServiceProcs.SaveParamsToXml(generator);
        }

        private void SaveParams(int GeneratedCount)
        {
            Generator generator = new Generator
            {
                dbHandler = new DBHandler { ServerName = textBoxServer.Text, Database = textBoxBase.Text, UserName = textBoxUser.Text, Pwd = textBoxPassword.Text, DomainAuth = checkBoxDomainAuth.Checked, Schema = "dbo" },
                GenerateFrom = GeneratedCount + 1,
                GenerateTo = numericUpDownTo.Value,
                PathToScript = textBoxPathToScript.Text
            };
            ServiceProcs.SaveParamsToXml(generator);
        }

        // Процедура генерации тестовых данных
        public void GenerateData()
        {
            Generator generator = new Generator
            {
                dbHandler = new DBHandler { ServerName = textBoxServer.Text, Database = textBoxBase.Text, UserName = textBoxUser.Text, Pwd = textBoxPassword.Text, DomainAuth = checkBoxDomainAuth.Checked, Schema = "dbo" },
                GenerateFrom = numericUpDownFrom.Value,
                GenerateTo = numericUpDownTo.Value,
                PathToScript = textBoxPathToScript.Text
            };
        }
        
        private void OK_button_Click(object sender, EventArgs e)
        {
            // Предварительно запишем параметры формы
            SaveParams();
            // Запустим генерацию
            // GenerateData();
            if (backgroundWorker1.IsBusy != true)
            {
                // Start the asynchronous operation.
                backgroundWorker1.RunWorkerAsync();
            }
            OK_button.Enabled = false;
        }

        // Процедура выводит данные в лог
        public void SetLogInfo(string LogInfo)
        {
            // Проверим, не вызывается ли контрол из потока
            if (richTextBoxInfo.InvokeRequired)
            {
                richTextBoxInfo.BeginInvoke(new Action(delegate
                {
                    SetLogInfo(LogInfo);
                }));
                return;
            }
            richTextBoxInfo.Text = richTextBoxInfo.Text + LogInfo + "\n";
        }
        
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Создадим экземпляр генератора
            Global_Generator = new Generator
            {
                dbHandler = new DBHandler { ServerName = textBoxServer.Text, Database = textBoxBase.Text, UserName = textBoxUser.Text, Pwd = textBoxPassword.Text, DomainAuth = checkBoxDomainAuth.Checked, Schema = "dbo" },
                GenerateFrom = numericUpDownFrom.Value,
                GenerateTo = numericUpDownTo.Value,
                PathToScript = textBoxPathToScript.Text
            };
            DBHandler dbHandler = Global_Generator.dbHandler;
            // Установим соединение
            dbHandler.Connect();
            bool connResult = dbHandler.Connect();
            if (!connResult)
            {
                MessageBox.Show(dbHandler.connectException.Message, MainResource.DialogHeaderError, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // Создадим экземпляр фонового процесса
            BackgroundWorker worker = sender as BackgroundWorker;

            // Прочитаем с диска скрипт
            Global_Generator.InitScript();
            if (!String.IsNullOrEmpty(Global_Generator.ExceptionText))
            {
                MessageBox.Show(Global_Generator.ExceptionText, MainResource.DialogHeaderError, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            SetLogInfo(MainResource.StartPoint + DateTime.Now);
            for (int i = Decimal.ToInt32(Global_Generator.GenerateFrom); i <= Decimal.ToInt32(Global_Generator.GenerateTo); i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    Global_Generator.GenerateData(i);
                    // Если в результате генерации была ошибка - покажем ее в логе
                    if (!String.IsNullOrEmpty(Global_Generator.ExceptionText) )
                    {
                        SetLogInfo("(i = "+i+") " + Global_Generator.ExceptionText);
                    }
                    worker.ReportProgress(i);
                }
            }
            dbHandler.connection.Close();
            SetLogInfo(MainResource.EndPoint + DateTime.Now);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.toolStripStatusLabel1.Text = "Generated " + e.ProgressPercentage.ToString() + " elements...";
            GeneratedCount = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                MessageBox.Show(MainResource.GenerationHasCanceled, MainResource.DialogHeaderInfo, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message, MainResource.DialogHeaderError, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show(MainResource.GenerationHasDone, MainResource.DialogHeaderInfo, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            this.toolStripStatusLabel1.Text = "";
        }

        // Процедура остановки генерации
        private void Cancel_Generation()
        {
            if (backgroundWorker1.WorkerSupportsCancellation == true)
            {
                // Cancel the asynchronous operation.
                backgroundWorker1.CancelAsync();
                // Предварительно запишем параметры формы (Начальная точка генерации для следующего запуска)
                SaveParams(GeneratedCount);
                numericUpDownFrom.Value = GeneratedCount;
                // Закроем соединение
                DBHandler dbHandler = Global_Generator.dbHandler;
                if (dbHandler.connection.State != ConnectionState.Closed) dbHandler.connection.Close();
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!backgroundWorker1.IsBusy) return;
            DialogResult result = MessageBox.Show(MainResource.ExitConfiramation, MainResource.DialogHeaderInfo, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                Cancel_Generation();
            }
        }

        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
        {
            if (backgroundWorker1 == null) return base.ProcessCmdKey(ref msg, keyData);
            if (!backgroundWorker1.IsBusy) return base.ProcessCmdKey(ref msg, keyData);
            try
            {
                if (msg.WParam.ToInt32() == (int)Keys.Escape)
                {
                    DialogResult result = MessageBox.Show(MainResource.ExitConfiramation, MainResource.DialogHeaderInfo, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                    {
                        Cancel_Generation();
                    }
                }
                else
                {
                    return base.ProcessCmdKey(ref msg, keyData);
                }
            }
            catch (Exception Ex)
            {
                MessageBox.Show("Key Overrided Events Error:" + Ex.Message);
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
}
